<?php

#namespace Giocondo;

# window -- A standard top level window.
class Window extends Container {
	protected $options = array(
		'child'         => '',
		'defaultHeight' => -1,
		'defaultWidth'  => -1,
		'title'         => '',
	);

	#const default_option = 'child';
	public $default_option = 'child';

	# The first Window created in this request.
	# Note class static members are not serialized.
	static protected $first = null;
 
	public function __construct($options = array()) {
		global $Giocondo_new_wid, $Giocondo_new_win;

		parent::__construct($options);

		unset($Giocondo_new_wid[$this->id]);
		$Giocondo_new_win[$this->id] = $this;

		if (is_null(self::$first)) {
			self::$first = $this;
		}
	}

	public function display($options=array(), $first = FALSE) {
		global $Giocondo_win_js;

		$Giocondo_win_js = sprintf('m(%u);', $this->id);
		parent::display();

		# Please note that SCRIPT is NOT an empty tag
		# see http://aspnetresources.com/blog/empty_vs_nonempty_html_tags.aspx
		if ($first) {
			# This is the first window to be displayed.
			require('GiocondoWindow.php');
		} else {
			require('GiocondoSubWindow.php');
		}
	}

	static public function first() {
		return self::$first;
	}

	# Template helper function.
	protected function display_child() {
		if ($this->options['child'] !== '') {
			$this->options['child']->display();
		}
	}

	# Template helper function.
	protected function has_js() {
		global $Giocondo_win_js, $Giocondo_new_win, $Giocondo_new_wid, $Giocondo_js;

		return $Giocondo_win_js !== '' || count($Giocondo_new_win)
			|| count($Giocondo_new_wid) || count($Giocondo_js);
	}

	# Template helper function.
	protected function display_first() {
		global $Giocondo_win_js;

		echo $Giocondo_win_js;
		Window::display_new(TRUE);
	}

	# Template helper function.
	static public function display_new($first = FALSE) {
		global $Giocondo_new_win, $Giocondo_new_wid, $Giocondo_win_js, $Giocondo_js;

		# TODO: what's better? use ob_start or return and catenate strings?
		foreach ($Giocondo_new_win as $id => $w) {
			if ($first && $id == self::$first->id) {
				continue;
			}
			ob_start();
			$w->display();

			$width = $w->cget('defaultWidth');
			$height = $w->cget('defaultHeight');
			if ($height == -1) {
				if ($width != -1) {
					$size = ",$width";
				} else {
					$size = '';
				}
			} else {
				$size = ",$width,$height";
			}

			printf("o(%u,'%s'%s);", $id, String::filter(ob_get_clean(), 'hj'),
				$size);
		}

		# For all new widget created but not displayed: display them capturing 
		# output using PHP output control facilities; then prepare a JavaScript 
		# statement to add the newly generated HTML code in the hide box so it's 
		# available for future use.
		foreach ($Giocondo_new_wid as $id => $w) {
				ob_start();
				$Giocondo_win_js = '';
				$w->display();
				printf("a(%u,'%s');", $id, String::filter(ob_get_clean(), 'hj'));
				# Since there may be options setted by configure calls on newly 
				# created widget which can only be configured with JavaScript, we must 
				# ensure the HTML for this widget exists before these calls are executed. 
				# Thus we must print JavaScript code after appending the widget to the hide box.
				echo $Giocondo_win_js;
		}

		# Emit JavaScript configuration code for newly displayed widgets.
		/*
		// TODO: DEBUG
		ob_start();
		print_r($Giocondo_js);
		Error::trigger(ob_get_clean());
		 */

		foreach ($Giocondo_js as $js) {
			echo implode(';', $js), ';';
		}
	}

	public function delete() {
		global $Giocondo_new_win;

		parent::delete();
		# TODO: what happens if I delete a window with a parent?
		unset($Giocondo_new_win[$this->id]);
	}

	public function onDelete() {
		return $this->onEvent('onDelete');
	}
}

# End of file
# vim: set ts=2 sw=2 noet:
?>
